package com.nfit.rabbitmq.consumer;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;


/**
 * ClassName:DefaultConsumer
 * Package:com.nfit.rabbitmq.consumer
 * Description
 *
 * 默认消费者 :
 *
 * @Author L
 * @Create 2024/11/21 15:29
 */
public class DefaultConsumer {

    /**
     * 自定义消息队列的名称
     */
    private static final String QUEUE_NAME = "default_queue";

    public static void main(String[] args) throws Exception {
        //初始化链接工厂并设置rabbitmq的主机地址
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");  // 设置RabbitMQ服务器的主机名为localhost
        factory.setPort(5672); //设置RabbitMQ服务器的AMQP通信端口为5672,1572是rabbitmq端口
        factory.setUsername("guest"); // 设置连接RabbitMQ服务器的用户名
        factory.setPassword("guest");  // 设置连接RabbitMQ服务器的密码

        //创建链接
        Connection conn = factory.newConnection();
        //使用链接构建一个通信通道
        Channel channel = conn.createChannel();
        //利用这个通道创建一个队列（如果队列存在测不会在创建）
        // 利用这个通道声明一个队列。如果队列已经存在，则此操作不会重复创建队列。
        // 参数解释：
        // QUEUE_NAME - 队列的名称
        // false - 是否持久化队列。如果为true，队列将在RabbitMQ服务器上持久化，即使服务器重启，队列和其中的消息也不会丢失。
        // false - 是否排他。如果为true，队列只能由声明它的连接使用，并且队列将在连接关闭时被删除。
        // false - 是否自动删除。如果为true，并且队列不再被任何消费者使用，队列将被自动删除。
        // null - 队列的其他参数，可以为null
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //接收消息,接收消息时会通过使用一个回调接口来接收
        //DeliverCallback是一个函数式接口
//        consumerTag：
//        consumerTag是一个字符串，它唯一地标识了这个消费者（即这个特定的消息接收者）。
//        RabbitMQ为每个注册到队列的消费者分配一个消费者标签（consumer tag）。这个标签在RabbitMQ内部用于跟踪消费者，并允许您取消特定的消费者。
//        delivery：
//        delivery是一个com.rabbitmq.client.Delivery对象，它包含了消息的详细信息。
//        delivery.getBody()方法返回消息的体（payload），它是一个字节数组。这通常是需要被处理的实际数据。
//        您可以使用delivery.getEnvelope()方法来获取关于消息的其他元数据，比如消息的路由键（routing key）、交换机（exchange）名称、消息ID等。
//        在您的代码中，您通过new String(delivery.getBody(), "UTF-8")将消息的体转换成了UTF-8编码的字符串，然后打印出来
//        简而言之，consumerTag是RabbitMQ用于跟踪消费者的标识符，而delivery包含了消息的体和其他相关元数据。
        DeliverCallback callback = (consumerTag, delivery) -> {
            //获取消息体
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println(message);
        };
        // 开始从指定的队列中接收消息
        // 参数解释：
        // QUEUE_NAME - 要从中接收消息的队列的名称
        // true - 自动确认消息。当消息被传递给消费者后，RabbitMQ将自动认为消息已被处理，并从队列中删除。
        // callback - 当消息到达时，将调用此回调接口来处理消息。
        // consumerTag -> {} - 这是一个消费者标签的回调，当消费者被取消或注册时，将调用此回调。在这个例子中，我们没有实现任何逻辑。
        channel.basicConsume(QUEUE_NAME, true, callback, consumerTag -> {});
    }
}
